/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
 *
 */

import { TaskDetails } from '@ohos/hvigor';
import fs from 'fs-extra';
import path from 'path';

import { CommonConst } from '../../const/common-const.js';
import { RuntimeOnlyObj } from '../../options/build/build-opt.js';
import { ModuleBuildProfile } from '../../options/build/module-build-profile.js';
import { ohPackageLoader } from '../../utils/loader/file/oh-package-loader';
import { OhosLogger } from '../../utils/log/ohos-logger.js';
import { HarExtendInfo } from '../har/har-extend-info.js';
import { TargetTaskService } from '../service/target-task-service.js';

import { OhosModuleTask } from './ohos-module-task.js';

const DEFAULT_MAIN_FILED_FILE_NAME = 'index';
export const DEFAULT_MAIN_FILED_FILE_SUFFIX = ['.ets', '.ts', '.js'];

const _log = OhosLogger.getLogger('process-package-json');

export interface PackageJsonOpt {
  name: string;
  version: string;
  ohos: {
    org: string;
    artifactType: string;
  };
  main: string;
  types?: string;
  parameterFile?: string;
}

export interface OhPackageJsonOpt {
  name: string;
  version: string;
  artifactType: string;
  main: string;
  types: string;
  metadata?: {
    workers?: string[];
    declarationEntry?: string[];
    runtimeOnly?: RuntimeOnlyObj;
    resource?: ModuleBuildProfile.ResourceBuildOpt;
    sourceRoot?: string[];
  };
  parameterFile?: string;
}

/**
 * OpenHarmony har的base task
 *
 * @since 2022/1/5
 */
export abstract class OhosHarTask extends OhosModuleTask {
  public readonly _harExtendInfo: HarExtendInfo;
  protected readonly modulePackageJsonPath: string;

  protected constructor(targetService: TargetTaskService, taskDetails: TaskDetails) {
    super(targetService, taskDetails);
    this._harExtendInfo = new HarExtendInfo(this.moduleModel, targetService.getBuildOption());
    this.modulePackageJsonPath = this.getModulePackageJsonPath();
    if (!this.packageJsonObj) {
      const fileName = ohPackageLoader.getNodeOhPackagePath(this.isOhpmProject ? CommonConst.OH_PACKAGE_JSON5 : CommonConst.PACKAGE_JSON);
      _log.printErrorExit('THE_%S_FILE_DOES_NOT_EXIST', [fileName, this.modulePackageJsonPath], [[fileName]]);
    }
  }

  private getModulePackageJsonPath() {
    return this.moduleModel.isOhpmProject() ? this.moduleModel.getOhPackageJson5Path() : this.moduleModel.getPackageJsonPath();
  }

  /**
   * 根据har模块下的package.json中main字段的配置,获取有效的main字段用于最终生成package.json
   * 1.配置了则使用配置的，并校验是否合法
   * 2.没有配置或者配置为空则按顺序检索模块根目录下存在哪种后缀的文件
   * 3.在2的基础上没有检索到,则默认使用index.ets为入口
   *
   * @returns {string}
   * @protected
   */
  protected getPackageJsonValidMainField(): string {
    const packageJsonMainFiled: string | undefined = this.packageJsonObj.main;
    let validMainField: string;
    if (packageJsonMainFiled === undefined || packageJsonMainFiled === '') {
      validMainField = this.findValidMainField();
    } else {
      validMainField = packageJsonMainFiled;
      const harExportMainEntryFilePath = path.resolve(this.moduleModel.getProjectDir(), validMainField);
      if (!fs.existsSync(harExportMainEntryFilePath)) {
        _log.printErrorExit('THE_MAIN_FIELD_SET_IN_PACKAGE_JSON_CORRSPONDING_PATH', [harExportMainEntryFilePath, this.modulePackageJsonPath]);
      }
    }
    return validMainField;
  }

  private findValidMainField(): string {
    const harModuleRoot = this.moduleModel.getProjectDir();

    let result;
    DEFAULT_MAIN_FILED_FILE_SUFFIX.forEach((suffix) => {
      const indexFileName = `${DEFAULT_MAIN_FILED_FILE_NAME}${suffix}`;
      const indexFilePath = path.resolve(harModuleRoot, `${DEFAULT_MAIN_FILED_FILE_NAME}${suffix}`);
      if (fs.existsSync(indexFilePath)) {
        result = indexFileName;
      }
    });

    return result ?? 'index.ets';
  }
}
